import React from "react";
import { Deploy } from "./manager/deploy";
import { useState, useEffect } from "react";
import { Register } from "./manager/register";
import { ProTable } from "@ant-design/pro-components";
import { postAllApps } from "@/services/hosting/api";
import { motion, AnimatePresence } from "framer-motion";
import { postAppControl } from "@/services/hosting/api";
import type { ProColumns } from "@ant-design/pro-components";
import { useNavigate, useLocation } from "react-router-dom";
import { EllipsisOutlined, PlusOutlined } from "@ant-design/icons";
import {
    Button,
    Dropdown,
    message,
    Space,
    Tag,
    Input,
    Switch,
    Typography,
    Tooltip,
} from "antd";
import {
    PoweroffOutlined,
    CaretRightOutlined,
    RedoOutlined,
    SearchOutlined,
    CloudUploadOutlined,
} from "@ant-design/icons";
import { postAllNodesList } from "@/services/nodes/api";

const { Text } = Typography;

const AppList: React.FC = () => {
    type TableListItem = {
        app_id: string;
        alias: string;
        version: string;
        stype: string;
        deploy_time: string;
        notes: string;
        status: string;
        file_name: string;
        node: string; // 添加node字段
    };

    // 简化App类型定义，统一包含所有字段
    type App = {
        app_id: string;
        before_id: string;
        alias: string;
        file_name: string;
        node: string;
        status: string;
        create_time: string;
        deploy_time: string;
        log_path: string;
        keepalive: string;
        notes: string;
        version: string;
        inpara: string;
        run_path: string;
        pid: string;
        port: string;
        porject: string;
        team: string;
        modules: string;
        runner: string;
        runner_version: string;
        create_user: string;
        source: string;
        time_dir: string;
        stype: string;
        nginx_conf: string;
    };

    const location = useLocation();
    const [showRegister, setShowRegister] = useState(false);
    const [showOverview, setShowOverView] = useState(false);
    const navigate = useNavigate();
    const [tableData, setTableData] = useState<TableListItem[]>([]);
    const [loadingAppIds, setLoadingAppIds] = useState<Record<string, boolean>>(
        {},
    );
    const [appsMap, setAppsMap] = useState<Record<string, App>>({});
    const [selectedAppId, setSelectedAppId] = useState<string | null>(null);
    const [refreshCooldown, setRefreshCooldown] = useState(0);
    const [loadingRefresh, setLoadingRefresh] = useState(false);
    const [searchText, setSearchText] = useState("");
    const [filteredData, setFilteredData] = useState<TableListItem[]>([]);
    const [showRunningOnly, setShowRunningOnly] = useState(false);
    const [showDeploy, setShowDeploy] = useState(false);
    const [isRegisterVisible, setIsRegisterVisible] = useState(false);
    const [isRegisterMounted, setIsRegisterMounted] = useState(false);
    const [isDeployVisible, setIsDeployVisible] = useState(false);
    const [isDeployMounted, setIsDeployMounted] = useState(false);
    const [appStats, setAppStats] = useState({
        total: 0,
        running: 0,
    });
    const [lastRefreshTime, setLastRefreshTime] = useState<Date | null>(null);
    const [timeSinceRefresh, setTimeSinceRefresh] = useState("");
    const [nodesMap, setNodesMap] = useState<Record<string, string>>({});
    const [loading, setLoading] = useState(true); // 添加加载状态

    // 从URL中获取nodeId
    const getUrlNodeId = () => {
        const params = new URLSearchParams(location.search);
        return params.get("node_id") || "0"; // 默认为'0'（本机节点）
    };

    const [nodeId, setNodeId] = useState(getUrlNodeId());

    // 监听URL变化
    useEffect(() => {
        const newNodeId = getUrlNodeId();
        setNodeId(newNodeId);
    }, [location.search]);

    // 获取节点列表信息
    useEffect(() => {
        const fetchNodes = async () => {
            try {
                const result = await postAllNodesList("0", navigate);
                if (result.status === "success") {
                    const nodesMapping: Record<string, string> = {};
                    result.message.forEach((node: any) => {
                        nodesMapping[node.node_id] =
                            node.host || node.ip || node.node_id;
                    });
                    setNodesMap(nodesMapping);
                }
            } catch (error) {
                console.error("获取节点列表失败:", error);
            }
        };

        fetchNodes();
    }, []);

    const statusColorMap: Record<string, string> = {
        running: "green",
        dead: "",
        error: "red",
        mapping: "green",
        unmapped: "",
    };

    const statusTextMap: Record<string, string> = {
        running: "运行中",
        dead: "未运行",
        error: "错误",
        mapping: "已启用",
        unmapped: "未启用",
    };

    const updateAppStats = (data: TableListItem[]) => {
        const runningCount = data.filter(
            (item) => item.status && item.status.toLowerCase() === "running",
        ).length;
        const mappingCount = data.filter(
            (item) => item.status && item.status.toLowerCase() === "mapping",
        ).length;
        setAppStats({
            total: data.length,
            running: mappingCount + runningCount,
        });
    };

    const handleSearchAndFilter = () => {
        let filtered = [...tableData];

        if (searchText.trim()) {
            filtered = filtered.filter(
                (item) =>
                    (item.alias &&
                        item.alias
                            .toLowerCase()
                            .includes(searchText.toLowerCase())) ||
                    (item.file_name &&
                        item.file_name
                            .toLowerCase()
                            .includes(searchText.toLowerCase())) ||
                    (item.version &&
                        item.version
                            .toLowerCase()
                            .includes(searchText.toLowerCase())) ||
                    (item.stype &&
                        item.stype
                            .toLowerCase()
                            .includes(searchText.toLowerCase())) ||
                    (item.status &&
                        item.status
                            .toLowerCase()
                            .includes(searchText.toLowerCase())),
            );
        }

        if (showRunningOnly) {
            filtered = filtered.filter(
                (item) =>
                    item.status && item.status.toLowerCase() === "running",
            );
        }

        setFilteredData(filtered);
    };

    const goAppMorePage = (app: TableListItem) => {
        navigate(
            `/hosting/more?appId=${app.app_id}&type=${app.stype}&nodeId=${app.node}`,
        );
    };

    const refreshAppList = async (showLoading: boolean = true) => {
        if (showLoading) {
            setLoading(true); // 只在手动刷新时设置loading状态
        }
        try {
            const apiResult = await postAllApps(navigate);
            if (apiResult.status === "error") {
                if (apiResult.status_code === "EXPIRED_TOKEN") {
                    window.location.href = "/login";
                }
            } else {
                const appsArray = Object.values(apiResult.message) as App[];
                const newTableData = appsArray.map((app) => ({
                    app_id: app.app_id,
                    alias: app.alias,
                    version: app.version,
                    stype: app.stype,
                    deploy_time: app.deploy_time,
                    notes: app.notes,
                    status: app.status,
                    file_name: app.file_name,
                    node: app.node, // 添加node字段
                }));

                const newAppsMap: Record<string, App> = {};
                appsArray.forEach((app) => {
                    newAppsMap[app.app_id] = app;
                });
                setAppsMap(newAppsMap);

                setTableData(newTableData);
                setFilteredData(newTableData);
                updateAppStats(newTableData);
            }
        } catch (error) {
            console.error("刷新应用程序失败：", error);
        } finally {
            if (showLoading) {
                setLoading(false); // 只在手动刷新时清除loading状态
            }
        }
    };

    const handleRefresh = async (): Promise<void> => {
        if (refreshCooldown > 0) return;

        setLoadingRefresh(true);
        try {
            await refreshAppList(true); // 手动刷新时显示loading
            const now = new Date();
            setLastRefreshTime(now);
            message.success("应用列表已刷新");

            setRefreshCooldown(5);
            const timer = setInterval(() => {
                setRefreshCooldown((prev) => {
                    if (prev <= 1) {
                        clearInterval(timer);
                        return 0;
                    }
                    return prev - 1;
                });
            }, 1000);
        } catch (error) {
            message.error("刷新失败");
        } finally {
            setLoadingRefresh(false);
        }
    };

    const toggleAppStatus = async (
        appId: string,
        currentStatus: string,
        stype: string,
        appNodeId: string, // 添加appNodeId参数
    ) => {
        let behavior = "NULL";
        if (stype === "static" || stype === "Static") {
            behavior = currentStatus === "mapping" ? "disable" : "enable";
        } else if (stype === "java" || stype === "Java") {
            behavior = currentStatus === "running" ? "stop" : "start";
        }
        setLoadingAppIds((prev) => ({
            ...prev,
            [appId]: true,
        }));

        try {
            const res = await postAppControl(
                { app_id: appId, behavior: behavior },
                stype,
                appNodeId, // 使用应用对应的nodeId
                navigate,
            );
            if (res === null) {
                // Do nothing
            } else {
                if (res.status === "success") {
                    await refreshAppList();
                    message.info(res.message as string);
                } else if (res.status === "error") {
                    message.warning(res.message as string);
                } else {
                    message.error("未知错误");
                }
            }
        } catch (error) {
            console.error("操作失败:", error);
            message.error("操作失败");
        } finally {
            setLoadingAppIds((prev) => ({
                ...prev,
                [appId]: false,
            }));
        }
    };

    const handleDeployClick = (appId: string) => {
        setSelectedAppId(appId);
        setShowDeploy(true);
        setIsDeployMounted(true);
        setTimeout(() => setIsDeployVisible(true), 10);
    };

    const DEFAULT_COLUMNS: ProColumns<TableListItem>[] = [
        {
            title: "名称",
            dataIndex: "alias",
            key: "alias",
            copyable: true,
        },
        {
            title: "文件名",
            dataIndex: "file_name",
            width: 400,
            copyable: true,
        },
        {
            title: "节点",
            dataIndex: "node",
            key: "node",
            sorter: (a, b) => {
                const nodeNameA = nodesMap[a.node] || a.node;
                const nodeNameB = nodesMap[b.node] || b.node;
                if (nodeNameA === "0") {
                    return "本机".localeCompare(nodeNameB);
                } else if (nodeNameB === "0") {
                    return nodeNameA.localeCompare("本机");
                }
                return nodeNameA.localeCompare(nodeNameB);
            },
            render: (_, record) => {
                const nodeName = nodesMap[record.node] || record.node;
                if (nodeName === "0") {
                    return <span>本机</span>;
                } else {
                    return <span>{nodeName}</span>;
                }
            },
        },
        {
            title: "版本号",
            dataIndex: "version",
            key: "version",
        },
        {
            title: "应用类型",
            dataIndex: "stype",
            ellipsis: true,
            key: "stype",
            sorter: (a, b) => {
                // 翻译stype用于排序
                const translateStype = (stype: string): string => {
                    if (stype === "static" || stype === "Static") {
                        return "前端静态文件";
                    } else if (stype === "java" || stype === "Java") {
                        return "Java服务";
                    } else {
                        return stype;
                    }
                };

                const stypeA = translateStype(a.stype);
                const stypeB = translateStype(b.stype);
                return stypeA.localeCompare(stypeB);
            },
            render: (_, record) => {
                // 翻译stype
                if (record.stype === "static" || record.stype === "Static") {
                    return <span>前端静态文件</span>;
                } else if (record.stype === "java" || record.stype === "Java") {
                    return <span>Java服务</span>;
                } else {
                    return <span>{record.stype}</span>;
                }
            },
        },

        {
            title: "状态",
            dataIndex: "status",
            ellipsis: true,
            key: "status",
            sorter: (a, b) => {
                const statusA =
                    statusTextMap[a.status?.toLowerCase() || ""] || a.status;
                const statusB =
                    statusTextMap[b.status?.toLowerCase() || ""] || b.status;
                return statusA.localeCompare(statusB);
            },
            render: (_, record) => (
                <Tooltip title={null} mouseEnterDelay={0}>
                    <Tag
                        color={
                            statusColorMap[
                                record.status?.toLowerCase() || ""
                            ] || "default"
                        }
                        style={{
                            fontWeight: "bold",
                            borderRadius: "4px",
                            padding: "0 8px",
                            minWidth: "60px",
                            textAlign: "center",
                        }}
                    >
                        {statusTextMap[record.status?.toLowerCase() || ""] ||
                            record.status}
                    </Tag>
                </Tooltip>
            ),
        },
        {
            title: "发布时间",
            dataIndex: "deploy_time",
            ellipsis: true,
            key: "deploy_time",
            sorter: (a, b) => {
                // 处理空值情况
                if (!a.deploy_time && !b.deploy_time) return 0;
                if (!a.deploy_time) return 1;
                if (!b.deploy_time) return -1;

                // 转换为日期对象进行比较
                const dateA = new Date(a.deploy_time);
                const dateB = new Date(b.deploy_time);

                // 检查日期有效性
                if (isNaN(dateA.getTime()) && isNaN(dateB.getTime())) return 0;
                if (isNaN(dateA.getTime())) return 1;
                if (isNaN(dateB.getTime())) return -1;

                return dateA.getTime() - dateB.getTime();
            },
        },
        {
            title: "操作",
            width: 180,
            key: "option",
            render: (_, record) => (
                <Space style={{ overflow: 'hidden' }}>
                    <AnimatePresence mode="wait">
                        {loadingAppIds[record.app_id] ? (
                            <motion.div
                                key={`loading-${record.app_id}`}
                                initial={{ opacity: 0, scale: 0.8 }}
                                animate={{ opacity: 1, scale: 1 }}
                                exit={{ opacity: 0, scale: 0.8 }}
                                transition={{ duration: 0.03 }}
                            >
                                <Button
                                    type="primary"
                                    danger={record.status === "running"}
                                    icon={
                                        record.status === "running" ? (
                                            <PoweroffOutlined />
                                        ) : (
                                            <CaretRightOutlined />
                                        )
                                    }
                                    loading={true}
                                />
                            </motion.div>
                        ) : record.status === "running" ||
                          record.status === "mapping" ? (
                            <motion.div
                                key={`stop-${record.app_id}`}
                                initial={{ opacity: 0, scale: 0.8 }}
                                animate={{ opacity: 1, scale: 1 }}
                                exit={{ opacity: 0, scale: 0.8 }}
                                transition={{ duration: 0.03 }}
                            >
                                <Tooltip title="停止" placement="top">
                                    <Button
                                        type="primary"
                                        danger
                                        icon={<PoweroffOutlined />}
                                        onClick={() =>
                                            toggleAppStatus(
                                                record.app_id,
                                                record.status,
                                                record.stype as
                                                    | "java"
                                                    | "static",
                                                record.node, // 传递应用的nodeId
                                            )
                                        }
                                    />
                                </Tooltip>
                            </motion.div>
                        ) : (
                            <motion.div
                                key={`start-${record.app_id}`}
                                initial={{ opacity: 0, scale: 0.8 }}
                                animate={{ opacity: 1, scale: 1 }}
                                exit={{ opacity: 0, scale: 0.8 }}
                                transition={{ duration: 0.03 }}
                            >
                                <Tooltip title="启动" placement="top">
                                    <Button
                                        type="primary"
                                        icon={<CaretRightOutlined />}
                                        onClick={() =>
                                            toggleAppStatus(
                                                record.app_id,
                                                record.status,
                                                record.stype as
                                                    | "java"
                                                    | "static",
                                                record.node, // 传递应用的nodeId
                                            )
                                        }
                                    />
                                </Tooltip>
                            </motion.div>
                        )}
                    </AnimatePresence>
                    <motion.div
                        whileHover={{ scale: 1.05 }}
                        whileTap={{ scale: 0.95 }}
                    >
                        <Tooltip title="发布" placement="top">
                            <Button
                                icon={<CloudUploadOutlined />}
                                onClick={() => handleDeployClick(record.app_id)}
                            />
                        </Tooltip>
                    </motion.div>
                    <motion.div
                        whileHover={{ scale: 1.05 }}
                        whileTap={{ scale: 0.95 }}
                    >
                        <Tooltip title="更多" placement="top">
                            <Button
                                icon={<EllipsisOutlined />}
                                onClick={() => goAppMorePage(record)}
                            />
                        </Tooltip>
                    </motion.div>
                </Space>
            ),
        },
    ];

    useEffect(() => {
        const initRefresh = async () => {
            await refreshAppList(true); // 页面初始化时显示loading
            setLastRefreshTime(new Date());
        };
        initRefresh();
    }, []);

    useEffect(() => {
        if (!lastRefreshTime) {
            setTimeSinceRefresh("");
            return;
        }

        const updateTime = () => {
            const seconds = Math.floor(
                (new Date().getTime() - lastRefreshTime.getTime()) / 1000,
            );

            if (seconds < 60) setTimeSinceRefresh(`${seconds}秒前`);
            else if (seconds < 3600)
                setTimeSinceRefresh(`${Math.floor(seconds / 60)}分钟前`);
            else if (seconds < 86400)
                setTimeSinceRefresh(`${Math.floor(seconds / 3600)}小时前`);
            else setTimeSinceRefresh(`${Math.floor(seconds / 86400)}天前`);
        };

        updateTime();
        const interval = setInterval(updateTime, 1000);

        return () => clearInterval(interval);
    }, [lastRefreshTime]);

    useEffect(() => {
        const interval = setInterval(async () => {
            await refreshAppList(false); // 定时刷新时不显示loading
        }, 10000);

        return () => clearInterval(interval);
    }, []);

    useEffect(() => {
        if (showRegister) {
            setIsRegisterMounted(true);
            setTimeout(() => setIsRegisterVisible(true), 10);
            return;
        } else {
            setIsRegisterVisible(false);
            const timer = setTimeout(() => setIsRegisterMounted(false), 300);
            return () => clearTimeout(timer);
        }
    }, [showRegister]);

    useEffect(() => {
        if (showDeploy) {
            setIsDeployMounted(true);
            setTimeout(() => setIsDeployVisible(true), 10);
            return;
        } else {
            setIsDeployVisible(false);
            const timer = setTimeout(() => setIsDeployMounted(false), 300);
            return () => clearTimeout(timer);
        }
    }, [showDeploy]);

    useEffect(() => {
        handleSearchAndFilter();
    }, [searchText, showRunningOnly, tableData]);

    return (
        <div style={{ height: "100%", overflow: "hidden" }}>
            <div
                style={{
                    background: "#fff",
                    padding: "16px 24px",
                    marginBottom: 16,
                    borderRadius: 8,
                    boxShadow: "0 1px 2px 0 rgba(0,0,0,0.03)",
                }}
            >
                <div
                    style={{
                        display: "flex",
                        justifyContent: "space-between",
                        alignItems: "center",
                        marginBottom: 16,
                    }}
                >
                    <Space size="large" style={{ marginTop: 20 }}>
                        <Text strong style={{ fontSize: 20 }}>
                            控制台
                        </Text>
                        <Text
                            type="secondary"
                            style={{
                                color: "#999",
                                marginTop: 20,
                            }}
                        >
                            将应用服务注册到渔翁，可以进行全生命周期的配置、管理
                        </Text>
                    </Space>

                    <Space size="large">
                        <div>
                            <Text type="secondary">应用总数: </Text>
                            <Text strong>{appStats.total}</Text>
                        </div>
                        <div>
                            <Text type="secondary">运行中: </Text>
                            <Text strong style={{ color: "#52c41a" }}>
                                {appStats.running}
                            </Text>
                        </div>
                        <div>
                            <Text type="secondary">上次手动刷新: </Text>
                            <Text strong>{timeSinceRefresh}</Text>
                        </div>
                    </Space>
                </div>
            </div>

            <ProTable<TableListItem>
                columns={DEFAULT_COLUMNS}
                request={async () => ({
                    data: filteredData,
                    success: true,
                })}
                dataSource={filteredData}
                rowKey="app_id"
                pagination={false}
                search={false}
                dateFormatter="string"
                loading={loading}
                onRow={(record) => {
                    return {
                        onClick: (e) => {
                            const target = e.target as HTMLElement;
                            const isInteractiveElement =
                                target.tagName === "BUTTON" ||
                                target.closest("button") ||
                                target.tagName === "A" ||
                                target.closest("a");

                            if (!isInteractiveElement) {
                                goAppMorePage(record);
                            }
                        },
                        style: {
                            cursor: "pointer",
                        },
                    };
                }}
                toolbar={{
                    title: (
                        <>
                            <div
                                style={{
                                    display: "flex",
                                    alignItems: "center",
                                    gap: 16,
                                }}
                            >
                                <span style={{ marginRight: 20 }}>
                                    应用列表
                                </span>
                            </div>
                            <div
                                style={{
                                    display: "flex",
                                    alignItems: "center",
                                    gap: 8,
                                }}
                            >
                                <Input
                                    placeholder="搜索"
                                    prefix={<SearchOutlined />}
                                    value={searchText}
                                    onChange={(e) =>
                                        setSearchText(e.target.value)
                                    }
                                    style={{ width: 200 }}
                                    allowClear
                                />
                                <div
                                    style={{
                                        display: "flex",
                                        alignItems: "center",
                                        gap: 8,
                                    }}
                                >
                                    <Switch
                                        checked={showRunningOnly}
                                        onChange={setShowRunningOnly}
                                        size="small"
                                        style={{ marginLeft: 20, marginTop: 3 }}
                                    />
                                    <span
                                        style={{ fontSize: 14, color: "#666" }}
                                    >
                                        仅运行中的应用
                                    </span>
                                </div>
                            </div>
                        </>
                    ),
                    actions: [
                        <Tooltip title="注册新应用">
                            <Button
                                type="primary"
                                onClick={() => setShowRegister(!showRegister)}
                                style={{ marginRight: 8, minWidth: 50 }}
                                icon={<PlusOutlined />}
                            />
                        </Tooltip>,
                        <Tooltip title="刷新">
                            <Button
                                icon={
                                    refreshCooldown > 0 ? null : (
                                        <RedoOutlined />
                                    )
                                }
                                onClick={handleRefresh}
                                loading={loadingRefresh}
                                disabled={refreshCooldown > 0}
                                style={{
                                    minWidth: "50px",
                                    cursor:
                                        refreshCooldown > 0
                                            ? "not-allowed"
                                            : "pointer",
                                    backgroundColor:
                                        refreshCooldown > 0
                                            ? "#f5f5f5"
                                            : undefined,
                                    color:
                                        refreshCooldown > 0
                                            ? "#d9d9d9"
                                            : undefined,
                                }}
                            >
                                {refreshCooldown > 0
                                    ? `${refreshCooldown}`
                                    : ""}
                            </Button>
                        </Tooltip>,
                    ],
                    settings: [],
                }}
                options={false}
                tableLayout="fixed"
                // stickyHeaderOffset={0}
            />
            <AnimatePresence>
                {isRegisterMounted && (
                    <motion.div
                        initial={{ opacity: 0, x: "100%" }}
                        animate={
                            isRegisterVisible
                                ? { opacity: 1, x: 0 }
                                : { opacity: 0, x: "100%" }
                        }
                        exit={{ opacity: 0, x: "100%" }}
                        transition={{ duration: 0.3, ease: "easeInOut" }}
                        style={{
                            position: "fixed",
                            top: 0,
                            right: 0,
                            width: "100%",
                            height: "100%",
                            zIndex: 1000,
                        }}
                    >
                        <Register
                            ifShow={isRegisterVisible}
                            setIfShow={(value) => {
                                setShowRegister(value);
                                if (!value) {
                                    setIsRegisterVisible(false);
                                }
                            }}
                            refreshAllApps={refreshAppList}
                        />
                    </motion.div>
                )}
            </AnimatePresence>
            <AnimatePresence>
                {isDeployMounted && (
                    <motion.div
                        initial={{ opacity: 0, x: "100%" }}
                        animate={
                            isDeployVisible
                                ? { opacity: 1, x: 0 }
                                : { opacity: 0, x: "100%" }
                        }
                        exit={{ opacity: 0, x: "100%" }}
                        transition={{ duration: 0.3, ease: "easeInOut" }}
                        style={{
                            position: "fixed",
                            top: 0,
                            right: 0,
                            width: "100%",
                            height: "100%",
                            zIndex: 1000,
                        }}
                    >
                        <Deploy
                            ifShow={isDeployVisible}
                            setIfShow={(value) => {
                                if (!value) {
                                    setIsDeployVisible(false);
                                    const timer = setTimeout(
                                        () => setIsDeployMounted(false),
                                        300,
                                    );
                                    return () => clearTimeout(timer);
                                }
                                setShowDeploy(value);
                                return;
                            }}
                            App={
                                selectedAppId
                                    ? appsMap[selectedAppId]
                                    : ({} as App)
                            }
                            refreshAllApps={refreshAppList}
                        />
                    </motion.div>
                )}
            </AnimatePresence>
        </div>
    );
};

export default AppList;
